﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OCRTheNewHope
{
    public enum FeatureType
    {
        NULL = 0,
        MINUS = 1,
        PLUS = 2,
    }

    public class Point
    {
        public int X { get; private set; }
        public int Y { get; private set; }
        
        public Point(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }
        
        public override string ToString()
        {
            return "(" + this.X.ToString() + "," + this.Y.ToString() + ")";
        }
    }

    public class Rectangle
    {
        public static Point LeftTop = new Point(4, 4);
        public static Point RightBottom = new Point(24, 24);

        public static Random rnd = new Random();
        
        public int Width { get; private set; }
        public int Height { get; private set; }
        
        public Point A { get; private set; }
        public Point B { get; private set; }
        public Point C { get; private set; }
        public Point D { get; private set; }
        
        // A  B
        // C  D
        
        public Rectangle()
        {
            int imageWidth = RightBottom.X - LeftTop.X;
            int imageHeight = RightBottom.Y - LeftTop.Y;

            int x1, y1, x2, y2;

            do
            {
                x1 = rnd.Next(imageWidth) + LeftTop.X;
                y1 = rnd.Next(imageHeight) + LeftTop.Y;

                x2 = rnd.Next(imageWidth) + LeftTop.X;
                y2 = rnd.Next(imageHeight) + LeftTop.Y;
            }
            while (x1 == x2 && y1 == y2);

            int xMin = Math.Min(x1, x2);
            int yMin = Math.Min(y1, y2);

            int xMax = Math.Max(x1, x2);
            int yMax = Math.Max(y1, y2);

            this.A = new Point(xMin, yMin);
            this.D = new Point(xMax, yMax);

            this.Width = this.D.X - this.A.X;
            this.Height = this.D.Y - this.A.Y;

            this.B = new Point(this.A.X + this.Width, this.A.Y);
            this.C = new Point(this.A.X, this.A.Y + this.Height);
        }

        public override string ToString()
        {
            return "(" + this.A.X.ToString() + ", " + this.A.Y.ToString() + "), W: " + this.Width.ToString() + ", H: " + this.Height.ToString();
        }
    }

    public class Feature
    {
        public static Random rnd = new Random();

        public FeatureType FeatureType { get; private set; }

        public static double[,] ThresholdCandidates { get; set; } // thresholds for minus and plus
        public double Threshold;

        public Rectangle Rectangle0 { get; private set; }
        public Rectangle Rectangle1 { get; private set; }

        public void Specify(int idx0, int idx1)
        {
            Threshold = Feature.ThresholdCandidates[idx0, idx1];
            if (idx0 == 0)
                this.FeatureType = FeatureType.MINUS;
            else
                this.FeatureType = FeatureType.PLUS;
        }

        public Feature()
        {            
            Rectangle0 = new Rectangle();
            Rectangle1 = new Rectangle();           
        }

        public override string ToString()
        {
            return "(" + this.Rectangle0.A.X.ToString() + ", " + this.Rectangle0.A.Y.ToString() + "), W: " + this.Rectangle0.Width.ToString() + ", H: " + this.Rectangle0.Height.ToString() + " || " +
                   "(" + this.Rectangle1.A.X.ToString() + ", " + this.Rectangle1.A.Y.ToString() + "), W: " + this.Rectangle1.Width.ToString() + ", H: " + this.Rectangle1.Height.ToString() + " "
                       + "Type: " + this.FeatureType.ToString();
        }
    }
}
